#pragma once

#include <type_traits>

namespace SE
{
    #define AutoRegisterSingleton(className) \
        public: \
            className(token) {} \
            ~className() = default; \
            className(const className&) = delete; \
            className& operator=(const className&) = delete;

    template<class _Ty>
    class Singleton
    {
    protected:
        struct token {};
        Singleton() noexcept = default;

    public:
        virtual ~Singleton() = default;
        Singleton(const Singleton&) = delete;
        Singleton(const Singleton&&) = delete;
        Singleton& operator=(const Singleton&) = delete;

        static _Ty& Get() noexcept(std::is_nothrow_constructible<_Ty>::value)
        {
            static _Ty instance {token{}};
            return instance;
        }
    };
} // !namespace SE